package application.view.gui;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import java.awt.event.ActionListener;

import application.view.gui.DuplicateMenuItemException;

/**
 * Provides an easy interface for creating or modifying JBarMenus
 * 
 * @author Philip Rasmussen & Morten Therkildsen
 */
public class MenuBuilder {

	private JMenuBar menuBar = new JMenuBar();;
	
	/**
	 * Constructor of the class
	 */
	public MenuBuilder(){

		// Do nothing
	}

	/**
	 * Constructor that bases its menu bar on a duplicate of the the passed JMenuBar. 
	 * 
	 * @param bar	the menu bar to duplicate. The properties copied from the JMenuItems in the JMenus of bar are the JMenuItem's name and any actionListeners associated with the JMenuItem.  
	 */
	public MenuBuilder(JMenuBar bar){
		
		if(bar == null) throw new NullPointerException("The JMenuBar was null.");
		if(bar.getMenuCount() == 0) throw new IllegalArgumentException("The JMenuBar does not contain any JMenu's.");
		
		int menuCount = bar.getMenuCount();		
		for(int i = 0 ; i < menuCount ; i++){

			JMenu menu = new JMenu(bar.getMenu(i).getAccessibleContext().getAccessibleName());
			int menuItemCount = bar.getMenu(i).getItemCount();
			for(int j = 0 ; j < menuItemCount ; ++j){

				JMenuItem menuItem = new JMenuItem(bar.getMenu(i).getItem(j).getAccessibleContext().getAccessibleName());
				ActionListener[] menuItemActionListeners = bar.getMenu(i).getItem(j).getActionListeners();
				for(ActionListener actionListener : menuItemActionListeners){

					menuItem.addActionListener(actionListener);
				}
				
				menu.add(menuItem);
			}

			menuBar.add(menu);			
		}
	}

	/**
	 * Add a new menu item to the menu bar with the name specified by the menu parameter.
	 * The menu item is added below the most recent added menu item in the specified menu.
	 * If the specified menu does not exist it will be added at the end of the menu bar.
	 * 
	 * @param menu	The menu the menu item should be added to.
	 * @param item	The menu item to add.
	 * @throws DuplicateMenuItemException	if the menu item already exists in the shared menu bar
	 */
	public void addMenuItem(String menuName, JMenuItem item) throws DuplicateMenuItemException {

		if(menuName == null) throw new NullPointerException("menuName was null.");
		if(item == null) throw new NullPointerException("item was null.");
		if(menuName.trim().length() == 0) throw new IllegalArgumentException("menuName was empty");
		
		int menuCount = menuBar.getMenuCount();		
		for(int i = 0 ; i < menuCount ; i++){

			/* If the menuName doesn't match the name of the menu, proceed to next menu */
			if(!menuBar.getMenu(i).getAccessibleContext().getAccessibleName().equals(menuName)) continue;

			JMenu menu = menuBar.getMenu(i);
			int menuItemCount = menuBar.getMenu(i).getItemCount();
			
			/* Compares the passed item's name with the j'th item's name in the i'th menu in menuBar */
			for(int j = 0 ; j < menuItemCount ; ++j)	
				if(item.getAccessibleContext().getAccessibleName().equals(menu.getItem(j).getAccessibleContext().getAccessibleName())) throw new DuplicateMenuItemException("The menu item already exists in the menu bar");
				
			menu.add(item, 0);
			return;
		}
		
		JMenu menu = new JMenu(menuName);
		menu.add(item);
		menuBar.add(menu);		
	}

	/**
	 * Removes a previously added menu item from the menu.
	 * If a menu is empty after this removal, the menu is also removed.
	 * 
	 * @param item	the menu item to remove
	 */
	public void removeMenuItem(JMenuItem item){
		
		if(item == null) throw new NullPointerException("item was null.");
		
		int menuCount = menuBar.getMenuCount();		
		for(int i = 0 ; i < menuCount ; i++){

			JMenu menu = menuBar.getMenu(i);
			int menuItemCount = menuBar.getMenu(i).getItemCount();
			for(int j = 0 ; j < menuItemCount ; ++j){
				
				if(menu.getItem(j).equals(item)){
					
					menu.remove(j);
					return;
				}
			}
		}
		/* item wasn't deleted from the menu bar because it wasn't in the menu bar in the first place */
	}

	/* POSSIBLE CODE DUPLICATION REDUCER
	private JMenuItem duplicateMenuItem(JMenuItem item){
		
		return new JMenuItem();
	}
	*/
	
	/**
	 * Returns the JMenuBar the object has constructed
	 * 
	 * @return	the menu bar previous calls to the object has constructed
	 */
	public JMenuBar getMenuBar(){

		return menuBar;
	}
}
